#include <assert.h>
#include "http.h"

HTTPResponse newEmptyResponse() {
    HTTPResponse response = {
        .code = HTTP_OK,
        .headers = newEmptyHeaders(),
        ._binaryBody = NULL,
        ._bodySize = 0,
        ._fileBody = NULL,
        ._useFileBody = false,
    };
    return response;
}

void freeHTTPResponse(HTTPResponse *res) {
    freeHeaders(&res->headers);
    if (res->_binaryBody != NULL) free(res->_binaryBody);
    if (res->_fileBody != NULL) fclose(res->_fileBody);
    res->code = HTTP_OK;
    res->_binaryBody = NULL;
    res->_bodySize = 0;
    res->_fileBody = NULL;
    res->_useFileBody = false;
}

bool makeEmptyResponse(HTTPResponse *res) {
    assert(res != NULL);
    freeHTTPResponse(res);
    return setContentLength(&res->headers, 0);
}

bool makeTextResponse(HTTPResponse *response, char* text, unsigned long textSize) {
    if (response == NULL) return false;
    if (text == NULL) return false;
    auto headers = &response->headers;
    setContentLength(headers, textSize);
    if(getContentType(headers) == NULL) setContentType(&response->headers, "text/plain");
    char *binaryBody = malloc(textSize+1);
    if (binaryBody == NULL) return false;
    strncpy(binaryBody, text, textSize);
    response->_bodySize = textSize;
    response->_binaryBody = binaryBody;
    response->_useFileBody = false;
    response->_fileBody = NULL;
    return true;
}

bool makeJSONResponse(HTTPResponse *response, char* json, unsigned long jsonSize) {
    if (response == NULL) return false;
    setContentType(&response->headers, "application/json");
    return makeTextResponse(response, json, jsonSize);
}

bool makeFileResponse(HTTPResponse *response, FILE* file) {
    if (response == NULL) return false;
    if (file == NULL) return false;
    auto headers = &response->headers;
    const size_t contentLength = getFileSize(file);
    setContentLength(headers, contentLength);
    if(getContentType(headers) == NULL) setContentType(headers, "application/octet-stream");
    response->_bodySize = contentLength;
    response->_binaryBody = NULL;
    response->_useFileBody = true;
    response->_fileBody = file;
    return true;
}

bool makeFilePathResponse(HTTPResponse *response, const char *filePath) {
    if (response == NULL) return false;
    FILE *file = fopen(filePath, "rb");
    setContentType(&response->headers, guessContentType(filePath));
    return makeFileResponse(response, file);
}
